/*
 * Copyright (c) 2013-2014 BlackBerry Limited.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "service.hpp"

#include <bb/Application>
#include <bb/platform/Notification>
#include <bb/platform/NotificationDefaultApplicationSettings>
#include <bb/system/InvokeManager>
#include <bb/data/DataSource>
#include <QtSql/QtSql>
#include <bb/data/SqlDataAccess>
#include <bb/data/DataAccessError>
#include <QTimer>

using namespace bb::platform;
using namespace bb::system;
using namespace bb::data;

Service::Service() :
        QObject(),
        m_notify(new Notification(this)),
        m_invokeManager(new InvokeManager(this))
{
    m_invokeManager->connect(m_invokeManager, SIGNAL(invoked(const bb::system::InvokeRequest&)),
            this, SLOT(handleInvoke(const bb::system::InvokeRequest&)));

    NotificationDefaultApplicationSettings settings;
    settings.setPreview(NotificationPriorityPolicy::Allow);
    settings.apply();
    init();
    onTimeout();
    start();
}

void Service::handleInvoke(const bb::system::InvokeRequest & request)
{
    if (request.action().compare("com.example.iFengNewsService.RESET") == 0) {
        QVariantMap data = request.metadata();
        QString opt = data["opt"].toString();

        if(opt == "restart"){
            restart();
        }
    }
}

void Service::start()
{
    timer = new QTimer();
    timer->setInterval(30000);
    connect(timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
    timer->start();
}

void Service::restart(){
    qDebug() << "Timer restart";
    timer->stop();
    timer->start();
    Notification::clearEffectsForAll();
    Notification::deleteAllFromInbox();
}

void Service::Notify(){
    //接收Form传来的信息
    qDebug() << "Notify";
}

void Service::onTimeout()
{
    loadHeadline();
}

void Service::loadHeadline(){
    QUrl url("http://api.iclient.ifeng.com/ClientNews?id=SYDT10");
    DataSource *ds = new DataSource();
    ds->setSource(url);
    QObject::connect(ds,SIGNAL(dataLoaded(const QVariant&)),this,SLOT(onLoadHeadlineChanged(const QVariant&)));
    ds->load();
}

void Service::onLoadHeadlineChanged(const QVariant &data){
    QVariantList list = data.value<QVariantList>();
    QVariantMap map = list.last().value<QVariantMap>();
    QList<QVariant> items = map["item"].toList();
    batchInsert(items);
}

void Service::notifyForm(QMap<QString, QVariant> &item){
    Notification * _notify = new Notification(this);
    _notify->setTitle(item["title"].toString());
    _notify->setBody(tr("%1").arg(item["updateTime"].toString()));

    QUrl url(item["id"].toString());
    bb::system::InvokeRequest request;
    request.setTarget("com.example.iFengNews");
    request.setAction("bb.action.START");
    request.setUri(url);
    _notify->setInvokeRequest(request);
    _notify->notify();
}

const QString dbFile = "./data/Headline.db";
void Service::init(){
    if(QFile::exists(dbFile)){
            return;
    }

    SqlDataAccess *sqlda = new SqlDataAccess(dbFile);
    const QString createSQL =  "CREATE TABLE Headline "
                                  "  (id INTEGER PRIMARY KEY AUTOINCREMENT, "
                                  "  title VARCHAR,"
                                  "  url VARCHAR);";

    sqlda->execute(createSQL);
    if(!sqlda->hasError()) {
        qDebug() << "Headline created.";
    } else {
        const DataAccessError error = sqlda->error();
        qDebug() << tr("Create table error: %1").arg(error.errorMessage());
    }

    sqlda->deleteLater();
}

void Service::batchInsert(QList<QVariant> &items){
    SqlDataAccess *sqlda = new SqlDataAccess(dbFile);

    const QString sqlList = "SELECT * FROM Headline";
    QVariant listResult = sqlda->execute(sqlList);
    if(sqlda->hasError()){
       return;
    }
    QVariantList list;
    if (!listResult.isNull()) {
       list = listResult.value<QVariantList>();
    }

    sqlda->deleteLater();

    for(int i=0;i<items.count();i++){
       QVariantMap item = items.at(i).value<QVariantMap>();
       QString title = item["title"].toString();
       QString url = item["id"].toString();

       for(int j=0;j<list.count();j++){
           QVariantMap subList = list.at(j).value<QVariantMap>();
           QString subUrl =subList["url"].toString();
           qDebug() << "subUrl-------"<<subUrl;
           qDebug() << "url-------" << url;
           if(subUrl == url){
               return;
           }
       }

       const QString sqlVerify = "SELECT * FROM Headline WHERE url = :url";
       QVariantList argsList;
       argsList << url;
       QVariant verificationResult = sqlda->execute(sqlVerify, argsList);
       if(sqlda->hasError()){
           qDebug() << "Next,Error*********************************";
           return;
       }

       if ((!verificationResult.isNull()) && verificationResult.value<QVariantList>().size() > 0) {
           qDebug() << tr("------------------------%1 Exist.------------------------%2").arg(title).arg(url);
           return;
       }

       notifyForm(item);

       QVariantList contact;
       contact << title << url;
       sqlda->execute("INSERT INTO Headline"
               " (title,url) "
               " VALUES (:title,:url)", contact);

       if (!sqlda->hasError()) {
           qDebug() << "Create record succeeded.";
       } else {
           const DataAccessError error = sqlda->error();
           qDebug() << tr("Create record error: %1").arg(error.errorMessage());
       }
    }

   sqlda->deleteLater();
}
